#include <windows.h>
#include <stdio.h>
#include "geometry.h"

LRESULT CALLBACK wndProc(HWND, UINT msg, WPARAM, LPARAM);
void onSizeChanged(HWND, WPARAM, LPARAM);
void onPaint(HWND);
void releaseBufferDC();

void testGeometryFunct(HWND);

HINSTANCE hInstance;
LPCWSTR clsName = L"deluanay";
LPCWSTR wndName = L"Demo building deluanay triangulatiohn";

HDC memoryDC;
RECT clientRect;
HBRUSH oldBrush, bgbrush;
HBITMAP oldBmp, hbmpBuffer;
HPEN oldPen, hPen = NULL;

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPreInst, LPSTR lpszCmdLine, int nShowCmd)
{
	MSG msg;
	WNDCLASSEX wndcls;
	HWND hwnd;

	hInstance = hInst;

	wndcls.cbSize        = sizeof(WNDCLASSEX);
	wndcls.style         = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
	wndcls.lpfnWndProc   = (WNDPROC) wndProc;
	wndcls.cbClsExtra    = 0;
	wndcls.cbWndExtra    = 0;
	wndcls.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
	wndcls.hCursor       = LoadCursor(NULL, IDC_ARROW);
	wndcls.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
	wndcls.lpszMenuName  = NULL;
	wndcls.lpszClassName = clsName;
	wndcls.hInstance     = hInstance;
	wndcls.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);

	RegisterClassEx(&wndcls);

	hwnd = CreateWindow(clsName,
			  wndName,
			  WS_OVERLAPPEDWINDOW,
			  CW_USEDEFAULT,
			  CW_USEDEFAULT,
			  CW_USEDEFAULT,
			  CW_USEDEFAULT,
			  NULL,
			  NULL,
			  hInstance,
			  NULL);

	if(!hwnd)
	{
		MessageBox(NULL, L"Cannot create window", L"Error", MB_OK);
		return 0;
	}

	ShowWindow(hwnd, nShowCmd);
	UpdateWindow(hwnd);

	while( GetMessage(&msg, NULL, 0, 0) )
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	return msg.wParam;
}

LRESULT CALLBACK wndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
	switch(msg)
	{
		case WM_SIZE:
			onSizeChanged(hwnd, wparam, lparam);
			break;

		case WM_LBUTTONDBLCLK:
			testGeometryFunct(hwnd);
			break;

		case WM_PAINT:
			onPaint(hwnd);
			break;

		case WM_ERASEBKGND:
			return TRUE;

		case WM_DESTROY:
		case WM_CLOSE:
			releaseBufferDC();
			PostQuitMessage(0);
			break;

		default:
			return DefWindowProc(hwnd, msg, wparam, lparam);
	}

	return 0;
}

void onPaint(HWND hwnd)
{
	PAINTSTRUCT ps;
	HDC hdc = BeginPaint(hwnd, &ps);	
	//copy from buffer DC to "real" DC
	BitBlt(hdc, 0, 0, clientRect.right - clientRect.left, clientRect.bottom - clientRect.top, memoryDC, 0, 0, SRCCOPY);
	EndPaint(hwnd, &ps);
}

void onSizeChanged(HWND hwnd, WPARAM wparam, LPARAM lparam)
{
	int height = HIWORD(lparam);
	int width = LOWORD(lparam);

	releaseBufferDC();
	HDC hdc = GetDC(hwnd);
	GetClientRect(hwnd, &clientRect);
	hbmpBuffer = CreateCompatibleBitmap(hdc, clientRect.right - clientRect.left, clientRect.bottom - clientRect.top);
	memoryDC = CreateCompatibleDC(hdc);

	bgbrush = CreateSolidBrush(RGB(200, 200, 200));
	oldBrush = (HBRUSH)SelectObject(memoryDC, bgbrush);
	hPen = CreatePen(PS_SOLID, 2, RGB(255, 0, 255));
	oldBmp = (HBITMAP)SelectObject(memoryDC, hbmpBuffer);
	oldPen = (HPEN)SelectObject(memoryDC, hPen);

	FillRect(memoryDC, &clientRect, bgbrush);
	ReleaseDC(hwnd, hdc);
}

void releaseBufferDC()
{
	if(hbmpBuffer != NULL)
	{
		SelectObject(memoryDC, oldBmp);
		SelectObject(memoryDC, oldPen);
		DeleteObject(hbmpBuffer);
		DeleteDC(memoryDC);
		DeleteObject(bgbrush);
		DeleteObject(hPen);
	}
}

void testGeometryFunct(HWND hwnd)
{
	Point2D p1, p2, p3;
	
	p1.x = 190;
	p1.y = 6.5;

	p2.x = 10;
	p2.y = 56.5;

	p3.x = 90;
	p3.y = 93.5;

	char r = counterClockwise(&p1, &p2, &p3);

	TCHAR s[20];
	swprintf(s,L"%d", r);
	RECT rect;
	rect.left = 100;
	rect.top = 100;
	rect.right = 150;
	rect.bottom = 120;
	DrawText(memoryDC, s, 20, &rect, DT_LEFT);
	//Ellipse(memoryDC, 100, 100, 150, 120);
	InvalidateRect(hwnd, NULL, false);
	
}